import 'package:casdon/common/widget/common_loading_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

/// 通用 Sliver 异步列表视图组件
class SliverAsyncListView<T> extends StatelessWidget {
  final AsyncValue<List<T>> asyncData;
  final VoidCallback? onRetry;
  final Widget? loadingView;
  final Widget? emptyView;

  final WidgetBuilder? loadingBuilder;
  final Widget Function(BuildContext, Object error)? errorBuilder;
  final WidgetBuilder? emptyBuilder;

  final Widget Function(BuildContext context, List<T> data) sliverBuilder;

  const SliverAsyncListView({
    super.key,
    required this.asyncData,
    this.onRetry,
    this.loadingView,
    this.emptyView,
    this.loadingBuilder,
    this.errorBuilder,
    this.emptyBuilder,
    required this.sliverBuilder,
  });

  Widget _buildSliverLoading(BuildContext context) => SliverToBoxAdapter(
    child: Padding(
      padding: const EdgeInsets.symmetric(vertical: 40),
      child: Center(child: loadingView ?? const CommonLoadingWidget()),
    ),
  );

  Widget _buildSliverError(BuildContext context, Object error) =>
      SliverToBoxAdapter(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 40),
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                errorBuilder?.call(context, error) ?? const Text('加载失败'),
                const SizedBox(height: 8),
                ElevatedButton(onPressed: onRetry, child: const Text('重试')),
              ],
            ),
          ),
        ),
      );

  Widget _buildSliverEmpty(BuildContext context) => SliverToBoxAdapter(
    child: Padding(
      padding: const EdgeInsets.symmetric(vertical: 40),
      child: Center(
        child:
            emptyBuilder?.call(context) ??
            Text('暂无数据', style: const TextStyle(color: Colors.grey)),
      ),
    ),
  );

  @override
  Widget build(BuildContext context) {
    return asyncData.when(
      loading: () => loadingBuilder != null
          ? SliverToBoxAdapter(child: loadingBuilder!(context))
          : _buildSliverLoading(context),
      error: (e, st) => errorBuilder != null
          ? SliverToBoxAdapter(child: errorBuilder!(context, e))
          : _buildSliverError(context, e),
      data: (list) {
        if (list.isEmpty) {
          return emptyBuilder != null
              ? SliverToBoxAdapter(child: emptyBuilder!(context))
              : _buildSliverEmpty(context);
        }

        return sliverBuilder(context, list);
      },
    );
  }
}
